#  /**
#  * Copyright (c) 2022 Beijing Jiaotong University
#  * PhotLab is licensed under [Open Source License].
#  * You can use this software according to the terms and conditions of the [Open Source License].
#  * You may obtain a copy of [Open Source License] at: [https://open.source.license/]
#  *
#  * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
#  * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
#  * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
#  *
#  * See the [Open Source License] for more details.
#  */
#  /**
#  * Author: Zheng Wang
#  * Created: Jul. 3, 2022
#  * Supported by: National Key Research and Development Program of China
#  */

import logging
from phot_engine.logical_structure.task_manager import TaskManager
from phot_engine.globals.task_status import TaskStatus
from phot_engine.core.simulation_task import SimulationTask
from multiprocessing import Queue


def _verify_task_id(task_id):
    if isinstance(task_id, str):
        return True
    else:
        return False


class PhotLabEngine:
    """
        PhotLabEngine is an entrance to manage simulation task
    """
    __task_dispatcher_manager = None

    def __init__(self):
        self.__task_dispatcher_manager = TaskManager()

    def add_task(self, task_id, task):
        """
            add a simulation task to task dispatcher manager
        :param task_id:
        :param task:
        :return:
        """
        if _verify_task_id(task_id):
            self.__task_dispatcher_manager.register_object(task_id=task_id,
                                                           task_obj=task)
            logging.debug("Computing Engine has added a simulation task "
                          "to dispatcher manager.task_id:{}".format(task_id))
            return True
        else:
            raise TypeError("task_id should str type not {}".format(type(task_id)))

    def cancel_task(self, task_id):
        self.__task_dispatcher_manager.cancel_dispatcher(task_id)

    def pause_task(self, task_id):
        self.__task_dispatcher_manager.pause_dispatcher(task_id)

    def recover_task(self, task_id):
        self.__task_dispatcher_manager.recover_dispatcher(task_id)

    def delete_task(self, task_id):
        self.__task_dispatcher_manager.delete_dispatcher(task_id)

    def calculate_task(self, task_id):
        try:
            self.__task_dispatcher_manager.use_dispatcher(task_id)
        except Exception as e:
            print(e)
            raise e

    def get_task(self, task_id):
        if self.__task_dispatcher_manager.get_object(task_id) is None:
            return None
        else:
            return self.__task_dispatcher_manager.get_object(task_id).get_task()

    def get_task_status(self, task_id):
        task_dispatcher_obj = self.__task_dispatcher_manager.get_object(task_id)
        if None is not task_dispatcher_obj:
            task_obj = task_dispatcher_obj.get_task()
            return task_obj.get_task_status()

    def get_task_exception_information(self, task_id) -> Queue:
        task_dispatcher_obj = self.__task_dispatcher_manager.get_object(task_id)
        if None is not task_dispatcher_obj:
            return task_dispatcher_obj.get_error_queue()
